using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.Xml;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Content;

namespace Dragoon.BreakIt
{
    /// <summary>
    /// A source can collide with collidables
    /// </summary>
    public interface ICollisionSource { };

    public class VoidEvent : EventArgs
    {
    }

    public class CollisionEvent : EventArgs
    {
        public readonly Vector3 Position;
        public readonly ICollisionSource Source;
        public readonly ICollidable Target;

        internal CollisionEvent(Vector3 position, ICollisionSource source, ICollidable target)
        {
            Position = position;
            Source = source;
            Target = target;
        }
    }


    public enum ModType
    {
        ChangePaddleLength,
        ExtraBall
    }

    namespace Data
    {
        public class CapsuleType
        {
            [XmlAttribute]
            public string Key;
            [XmlAttribute]
            public ModType Modification;
            [XmlAttribute]
            public string Value;
            public Point ImagePos;
            public float Speed;
        }

        public class BlockType
        {
            [XmlAttribute] public string Key;
            /// <summary>
            /// The Point of the source image block on arinoid.png 
            /// </summary>
            public  Point ImagePos;
            [XmlAttribute]
            public int MaxHitCount;
            [XmlAttribute]
            public int Reward;
        }
    }

    public class CapsuleType : DataBased<Data.CapsuleType>
    {
        public readonly Rectangle ImageSourceArea;

        internal CapsuleType(Data.CapsuleType data) : base(data) 
        {
            ImageSourceArea = new Rectangle(
                    (32 * data.ImagePos.X) + 2,
                    (32 * data.ImagePos.Y) + 2, 30, 15);

        }

        public char Key
        {
            get { return _data.Key[0]; }
        }

        public float Speed
        {
            get { 
                return _data.Speed * Geometry.MaxY; 
            }
        }
        
        public ModType Type
        {
            get { return _data.Modification; }
        }

        public bool ValueAsBool
        {
            get { return bool.Parse(_data.Value); }
        }

        public double ValueAsDouble 
        {
            get { return double.Parse(_data.Value); } 
        }

        public bool Equals(CapsuleType other)
        {
            return Key.Equals(other.Key);
        }

    }

    public class CapsuleTypeSet : Set<CapsuleType, char>
    {
        public override char KeyOf(CapsuleType elem)
        {
            return elem.Key;
        }
    }

    public class BlockType : DataBased<Data.BlockType>
    {
        /// <summary>
        /// The area in the composite bitmap from which the image for the <see cref="BlockType"/> 
        /// must be grabbed.
        /// </summary>
        public readonly Rectangle ImageSourceArea;

        internal BlockType(Data.BlockType data) : base(data) 
        {
            ImageSourceArea = new Rectangle(
                (32 * data.ImagePos.X) + 2, 
                (32 * data.ImagePos.Y) + 2 , 30, 15);
        }
        public char Key { get { return _data.Key[0]; } }

        public int Reward { get { return _data.Reward; } }
        internal int MaxHitCount
        {
            get
            {
                return _data.MaxHitCount;
            }
        }

    }

    public class BlockTypeSet : Set<BlockType,char>
    {
        public override char KeyOf(BlockType elem)
        {
            return elem.Key;
        }

    }
}
